package com.scheduled;

import com.gavel.database.SQLExecutor;
import com.jd.open.api.sdk.DefaultJdClient;
import com.jd.open.api.sdk.JdClient;
import com.mrobuy.jd.api.Jos;
import com.mrobuy.type.ApplyState;
import com.mrobuy.jdvc.dao.JDAccountDao;
import com.mrobuy.jdvc.dao.SyncLogDao;
import com.mrobuy.jdvc.dao.SyncStatDao;
import com.mrobuy.jdvc.entity.*;
import com.mrobuy.util.IdentifierGen;
import com.util.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 *
 *  商品申请列表同步
 *
 */
@Component
public class ProductApplySyncTask {

    private static Logger LOG = LoggerFactory.getLogger(ProductApplySyncTask.class);

    private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");

    private static final DateFormat THE_DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");

    private static final  String APINAME = "jingdong.vc.item.product.applies.find";

    @Autowired
    private JDAccountDao jdAccountDao;

    @Autowired
    private SyncStatDao syncStatDao;

    @Autowired
    private SyncLogDao syncLogDao;

    // 0 0 10,14,17 * * ? 每天上午10点，下午2点，4点
    // @Scheduled(cron="0 36 6,17,23 * * ?")
    @Scheduled(fixedRate = 1000*60*30)
    public void exec() {

        if ( !TaskSwitch.APPLY_SYNC.get() ) {
            return;
        }

        List<JDAccount> accounts = jdAccountDao.list();
        LOG.info("JDAccount: " + (accounts==null ? 0 : accounts.size()));
        if ( accounts==null || accounts.size()==0 ) {
            return;
        }

        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        Date todayBegin = calendar.getTime();


        for (JDAccount account : accounts) {
            boolean sync = "Y".equalsIgnoreCase(account.getAutoSync());
            LOG.info("[商品申请列表][{}]供应商简码: {}; 自动同步: {}", account.getName(), account.getVccode(), sync);
            if ( sync ) {
                while ( true ) {
                    Date lastTime =  syncProductApply(account);
                    if ( lastTime==null || lastTime.after(todayBegin) ) {
                        break;
                    }
                }
            }
        }
    }

    private Date syncProductApply(JDAccount account) {
        if ( account==null ) {
            return null;
        }



        SyncState syncState = syncStatDao.load(account.getVccode(), APINAME);
        if ( syncState==null ) {
            syncState = new SyncState();
            syncState.setId(IdentifierGen.uuid());
            syncState.setShopName(account.getVccode());
            syncState.setName(APINAME);
            syncStatDao.insert(syncState);
        }

        try {
            Date endTime = sync(account, syncState.getTheDate());
            syncState.setTheDate(endTime);
            return endTime;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            syncState.setUpdateTime(Calendar.getInstance().getTime());
            syncStatDao.update(syncState);
            LOG.info("[{}({})]同步完成", account.getName(), account.getVccode());
        }
    }

    private Date sync(JDAccount account, Date beginTime) throws Exception {

        String beginTimeStr = null;
        String endTimeStr = null;

        Date beginOfToday = DateUtils.beginOfDay();

        Date endTime = null;
        if ( beginTime==null ) {
            // 开始时间为空, 初始加载3个月之前的数据
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.HOUR_OF_DAY, 23);
            calendar.set(Calendar.MINUTE, 59);
            calendar.set(Calendar.SECOND, 59);
            calendar.set(Calendar.MILLISECOND, 0);
            calendar.add(Calendar.MONTH, -3);
            endTime = calendar.getTime();
        } else {
            // 开始时间不为空, 每次加载1天的数据
            if ( beginTime.after(beginOfToday) ) {
                beginTimeStr = DATE_FORMAT.format(DateUtils.beginOfDay());
                endTime = DateUtils.endOfDay();
            } else {
                beginTimeStr = DATE_FORMAT.format(beginTime);
                endTime = DateUtils.addDay(beginTime, 1);
            }
        }
        endTimeStr = DATE_FORMAT.format(endTime);

        SyncLog syncLog = new SyncLog(IdentifierGen.uuid());
        try {
            syncLog.setShopName(account.getName());
            syncLog.setAppkey(account.getAppkey());
            syncLog.setThedate(THE_DATE_FORMAT.format(Calendar.getInstance().getTime()));
            syncLog.setName(APINAME);
            syncLog.setParams("[" + beginTimeStr + ", " + endTimeStr + "]");
            syncLog.setStarttime(Calendar.getInstance().getTime());

            JdClient client = new DefaultJdClient(Jos.SERVER, account.getAccess_token(),  account.getAppkey(), account.getAppsecret());

            List<VCProductApply> productApplies = Jos.productApplyFindClient(client)
                                                    .setBeginTime(beginTimeStr)
                                                    .setEndTime(endTimeStr)
                                                    .call();

            if ( productApplies!=null ) {
                for (VCProductApply productApply : productApplies) {
                    productApply.setVendor(account.getVccode());
                    VCProductApply exist = SQLExecutor.executeQueryBean("select * from VC_PRODUCT_APPLY where APPLYID = ?", VCProductApply.class, productApply.getApplyId());

                    ApplyState applyState = ApplyState.getStateByCode(productApply.getState());
                    productApply.setReject(applyState.reject());
                    if ( exist==null ) {
                        productApply.setZt(1);
                        SQLExecutor.insert(productApply);
                    } else {
                        SQLExecutor.update(productApply);
                    }
                }
            }
            syncLog.setState("success");
        } catch (Exception e) {
            syncLog.setState("failed");
            syncLog.setMessage(e.getMessage());
            throw e;
        } finally {
            syncLog.setEndtime(Calendar.getInstance().getTime());
            syncLogDao.insert(syncLog);
        }

        return endTime;
    }
}
